using UnityEngine;
using System.Collections;
using System.Collections.Generic;

public class MagicInfoPanel : MonoBehaviour {
	public UIPopupList classList;
	public string classListSetupForCharacterName;
	
	public GameObject spellsPerDayObject;
	SpellsPerDayDisplayTemplate spellsPerDay_Template;
	
	public GameObject spellsKnownButton;
	public GameObject spellsKnownLevelButton;
	public GameObject spellsKnownSpellTemplate;
	
	public GameObject spellsPreparedButton;
	public GameObject spellsPreparedLevelButton;
	public GameObject spellsPreparedSpellTemplate;
	
	CharacterClass currentSelectedClass;
	
	bool SpellsKnownButtonExpanded = false;
	bool[] SpellsKnownLevelExpanded = new bool[]{false,false,false,false,false,false,false,false,false,false};
	
	bool SpellsPreparedButtonExpanded = false;
	bool[] SpellsPreparedLevelExpanded = new bool[]{false,false,false,false,false,false,false,false,false,false};
	
	bool SpellPerDayExpanded = true;
	
	List<GameObject> ListElements;
	
	public UITable table;
	
	string lastSelection = "No Caster Classes";
	
	void Start()
	{
		ListElements = new List<GameObject>();
		
		spellsPerDay_Template = spellsPerDayObject.GetComponent<SpellsPerDayDisplayTemplate>();
		
		spellsPerDayObject.SetActiveRecursively(false);
		spellsKnownLevelButton.SetActiveRecursively(false);
		spellsPreparedLevelButton.SetActiveRecursively(false);
		spellsKnownSpellTemplate.SetActiveRecursively(false);
		spellsPreparedSpellTemplate.SetActiveRecursively(false);
		
		UIButtonMessage message = spellsKnownButton.AddComponent<UIButtonMessage>();
		message.target = gameObject;
		message.functionName = "ExpandSpellsKnown";
		
		message = spellsPreparedButton.AddComponent<UIButtonMessage>();
		message.target = gameObject;
		message.functionName = "ExpandSpellsPrepared";
		
		message = spellsPerDayObject.AddComponent<UIButtonMessage>();
		message.target = gameObject;
		message.functionName = "SpellsPerDayOptions";
		
		//classList.gameObject.AddComponent<Po
		
		ReloadFromCurrentCharacter();
	}
	
	void Update()
	{
		if(lastSelection != classList.selection)
		{
			lastSelection = classList.selection;
			ReloadFromCurrentCharacter();
		}
	}
	
	public void ReloadFromCurrentCharacter()
	{
		if(string.IsNullOrEmpty(classListSetupForCharacterName) || classListSetupForCharacterName != SheetManager.activeCharacter.name)
		{
			classList.items = SheetManager.activeCharacter.classes.FindAll(cl => cl.MagicUser).ConvertAll<string>(cl => cl.name);
			
			if(currentSelectedClass == null)
			{
				currentSelectedClass = SheetManager.activeCharacter.classes.Find(c => c.MagicUser);
				if(currentSelectedClass == null)
				{
					classList.items = new List<string>{"No Caster Classes"};
					CloseAllWindows();
					return;
				}
			}
			
			if(classList.items.Find(cn => cn == currentSelectedClass.name) != null)
				classList.selection = currentSelectedClass.name;
			else 
				classList.selection = classList.items[0];
		}
		
		currentSelectedClass = SheetManager.activeCharacter.classes.Find(cl => cl.name == classList.selection);
		
		CloseAllWindows();
		
		if(currentSelectedClass != null)
		{
			if(currentSelectedClass.spellsKnown != null)
				spellsPreparedButton.SetActiveRecursively(false);
			else
				spellsPreparedButton.SetActiveRecursively(true);
			
			if(SpellPerDayExpanded)
			{
				DisplaySpellPerDayInfo();
			}
			
			if(SpellsKnownButtonExpanded)
			{
				DisplaySpellsKnownInfo();
			}
			
			if(SpellsPreparedButtonExpanded)
			{
				DisplaySpellsPreparedInfo();
			}
		}
		
		classListSetupForCharacterName = SheetManager.activeCharacter.name;
		
		table.repositionNow = true;
	}
	
	void DisplaySpellPerDayInfo()
	{
		spellsPerDayObject.SetActiveRecursively(true);
		
		foreach(var i in currentSelectedClass.spellsPerDay.spellTable[currentSelectedClass.level])
		{
			if(i.Value >= 0)
			{
				spellsPerDay_Template.SetSpellsCountLabel(i.Key, (i.Value + SheetManager.activeCharacter.bonusSpellsByLevel(i.Key, currentSelectedClass.SpellcastingAbility)).ToString());
				if(i.Key > 0)
					spellsPerDay_Template.SetSpellsUsedLabel(i.Key,currentSelectedClass.spellsUsed[i.Key-1]);
			}
			else
			{
				spellsPerDay_Template.SetSpellsCountLabel(i.Key, "-");
				if(i.Key > 0)
					spellsPerDay_Template.SetSpellsUsedLabel(i.Key,"-");
			}
			
		}
	}
	
	void DisplaySpellsKnownInfo()
	{
		foreach(var spellLevel in currentSelectedClass.spellsPerDay.spellTable[currentSelectedClass.level])
		{
			if(spellLevel.Value >= 0)
			{
				spellsKnownLevelButton.SetActiveRecursively(true);
				
				GameObject levelButton = Instantiate(spellsKnownLevelButton) as GameObject;
				levelButton.transform.parent = spellsKnownLevelButton.transform.parent;
				levelButton.transform.localPosition = spellsKnownLevelButton.transform.localPosition;
				levelButton.transform.localScale = spellsKnownLevelButton.transform.localScale;
				SpellLevelDisplayTemplate template = levelButton.GetComponent<SpellLevelDisplayTemplate>();
				
				levelButton.name += "_"+spellLevel.Key;
				ListElements.Add(levelButton);
				
				template.spellLevel = spellLevel.Key;
				template.LevelLabel.text = "Level " + spellLevel.Key;
				if(currentSelectedClass.spellsKnown != null)
				{
					template.secondLabel.text = currentSelectedClass.spellsKnown.spellTable[currentSelectedClass.level][spellLevel.Key] + " Known";
				}
				else
				{
					template.secondLabel.text = "";
				}
				
				UIButtonMessage pressandholdmessage = levelButton.AddComponent<UIButtonMessage>();
				pressandholdmessage.trigger = UIButtonMessage.Trigger.OnPressAndHold;
				pressandholdmessage.functionName = "AddAKnownSpell";
				pressandholdmessage.target = gameObject;
				UIButtonMessage message = template.gameObject.AddComponent<UIButtonMessage>();
				message.target = gameObject;
				message.functionName = "ExpandSpellsKnownLevel";
				
				if(SpellsKnownLevelExpanded[spellLevel.Key])
				{
					foreach(var spell in currentSelectedClass.SpellsCurrentlyKnown.FindAll(
						s => s.MatchesListAndLevel(currentSelectedClass.SpellList, spellLevel.Key)))
					{
						DisplayKnownSpellInfo(spell, spellLevel.Key);
					}
				}
				
				spellsKnownLevelButton.SetActiveRecursively(false);
			}
		}
	}
	
	void AddAKnownSpell(GameObject go)
	{
		SpellLevelDisplayTemplate template = go.GetComponent<SpellLevelDisplayTemplate>();
		
		BrowserManager.CreateSpellBrowser_SubIndex(gameObject, 
			"AddAKnownSpell_Callback", new List<string>(), currentSelectedClass.SpellList, template.spellLevel);
	}
	
	void AddAKnownSpell_Callback(List<string> spells)
	{
		if(spells != null)
		{
			foreach(string spellName in spells)
			{
				if(currentSelectedClass.SpellsCurrentlyKnown.Find(s => s.name == spellName) == null)
				{
					currentSelectedClass.SpellsCurrentlyKnown.Add(SpellManager.Load(spellName));
				}
			}
			
			SheetManager.SaveActiveCharacter();
			ReloadFromCurrentCharacter();
		}
	}
	
	void ExpandSpellsKnown()
	{
		SpellsKnownButtonExpanded = !SpellsKnownButtonExpanded;
		ReloadFromCurrentCharacter();
	}
	
	void ExpandSpellsKnownLevel(GameObject go)
	{
		SpellLevelDisplayTemplate template = go.GetComponent<SpellLevelDisplayTemplate>();
		
		SpellsKnownLevelExpanded[template.spellLevel] = !SpellsKnownLevelExpanded[template.spellLevel];
		
		ReloadFromCurrentCharacter();
	}
	
	void DisplayKnownSpellInfo(Spell spell, int level)
	{
		spellsKnownSpellTemplate.SetActiveRecursively(true);
		
		GameObject spellObject = Instantiate(spellsKnownSpellTemplate) as GameObject;
		spellObject.transform.parent = spellsKnownSpellTemplate.transform.parent;
		spellObject.transform.localPosition = spellsKnownSpellTemplate.transform.localPosition;
		spellObject.transform.localScale = spellsKnownSpellTemplate.transform.localScale;
		spellObject.name += "_"+level+"_"+spell.name;
		
		SpellTemplate template = spellObject.GetComponent<SpellTemplate>();
		template.spellName.text = spell.name;
		template.descriptionBlock.text ="Click to View Info or Remove.";
		template.spell = spell;
		
		UIButtonMessage message = spellObject.AddComponent<UIButtonMessage>();
		message.target = gameObject;
		message.functionName = "ViewKnownSpellOptions";
		
		ListElements.Add(spellObject);
		
		spellsKnownSpellTemplate.SetActiveRecursively(false);
	}
	
	IEnumerator ViewKnownSpellOptions(GameObject go)
	{
		SpellTemplate template = go.GetComponent<SpellTemplate>();
		
		List<string> options = new List<string>{"Remove Spell", "View Info"};
		
		if(currentSelectedClass.spellsKnown == null)
		{
			options.Add("Prepare Spell");
		}
		
		List<SetterWindowDescription> optionsList = new List<SetterWindowDescription>
		{
			new SetterWindowDescription("option", "", false, options, false)
		};
		
		yield return StartCoroutine(HelperFunctions.SetterWindow("Do What?", optionsList));
		
		if(optionsList[0].outVariable != null)
		{
			switch(optionsList[0].outVariable)
			{
			case "Remove Spell":
				RemoveKnownSpell(go);
				break;
			case "View Info":
				ViewSpellInfo(go);
				break;
			case "Prepare Spell":
				PrepareKnownSpell(go);
				break;
			}
		}
		
		yield break;
	}
	
	void ViewSpellInfo(GameObject go)
	{
		SpellTemplate template = go.GetComponent<SpellTemplate>();
		
		GameObject g = Instantiate(GameReference.reference.NewSpellWindowPrefab) as GameObject;
		g.transform.parent = GameReference.reference.BaseMenuPanel;
		g.transform.localScale = Vector3.one;
		BrowserManager.currentNewTransform = g.transform;
		g.transform.localPosition = BrowserManager.CurrentIndex;
		
		SpellEditorMenu w = g.GetComponent<SpellEditorMenu>();
		w.LoadSpellDisplay(template.spell.name, true);
	}
	
	void RemoveKnownSpell(GameObject go)
	{
		SpellTemplate template = go.GetComponent<SpellTemplate>();
		
		currentSelectedClass.SpellsCurrentlyKnown.Remove(template.spell);
		
		SheetManager.SaveActiveCharacter();
		ReloadFromCurrentCharacter();
	}
	
	void PrepareKnownSpell(GameObject go)
	{
		SpellTemplate template = go.GetComponent<SpellTemplate>();
		
		currentSelectedClass.SpellsPrepared.Add(template.spell);
		
		SheetManager.SaveActiveCharacter();
		ReloadFromCurrentCharacter();
	}
	
	void DisplaySpellsPreparedInfo()
	{
		if(currentSelectedClass.spellsKnown != null)
			return;		
		
		foreach(var spellLevel in currentSelectedClass.spellsPerDay.spellTable[currentSelectedClass.level])
		{
			if(spellLevel.Value >= 0)
			{
				spellsPreparedLevelButton.SetActiveRecursively(true);
				
				GameObject levelButton = Instantiate(spellsPreparedLevelButton) as GameObject;
				levelButton.transform.parent = spellsPreparedLevelButton.transform.parent;
				levelButton.transform.localPosition = spellsPreparedLevelButton.transform.localPosition;
				levelButton.transform.localScale = spellsPreparedLevelButton.transform.localScale;
				SpellLevelDisplayTemplate template = levelButton.GetComponent<SpellLevelDisplayTemplate>();
				
				levelButton.name += "_"+spellLevel.Key;
				ListElements.Add(levelButton);
				
				template.spellLevel = spellLevel.Key;
				template.LevelLabel.text = "Level " + spellLevel.Key;
				template.secondLabel.text = "";
				
				UIButtonMessage message = template.gameObject.AddComponent<UIButtonMessage>();
				message.target = gameObject;
				message.functionName = "ExpandSpellsPreparedLevel";
				
				if(SpellsPreparedLevelExpanded[spellLevel.Key])
				{
					foreach(var spell in currentSelectedClass.SpellsPrepared.FindAll(
						s => s.MatchesListAndLevel(currentSelectedClass.SpellList, spellLevel.Key)))
					{
						DisplayPreparedSpellInfo(spell, spellLevel.Key);
					}
				}
				
				spellsPreparedLevelButton.SetActiveRecursively(false);
			}
		}
	}
	
	void ExpandSpellsPrepared()
	{
		SpellsPreparedButtonExpanded = !SpellsPreparedButtonExpanded;
		ReloadFromCurrentCharacter();
	}
	
	void ExpandSpellsPreparedLevel(GameObject go)
	{
		SpellLevelDisplayTemplate template = go.GetComponent<SpellLevelDisplayTemplate>();
		
		SpellsPreparedLevelExpanded[template.spellLevel] = !SpellsPreparedLevelExpanded[template.spellLevel];
		
		ReloadFromCurrentCharacter();
	}
	
	void DisplayPreparedSpellInfo(Spell spell, int level)
	{
		spellsPreparedSpellTemplate.SetActiveRecursively(true);
		
		GameObject spellObject = Instantiate(spellsPreparedSpellTemplate) as GameObject;
		spellObject.transform.parent = spellsPreparedSpellTemplate.transform.parent;
		spellObject.transform.localPosition = spellsPreparedSpellTemplate.transform.localPosition;
		spellObject.transform.localScale = spellsPreparedSpellTemplate.transform.localScale;
		spellObject.name += "_"+level+"_"+spell.name;
		
		SpellTemplate template = spellObject.GetComponent<SpellTemplate>();
		template.spellName.text = spell.name;
		template.descriptionBlock.text ="Click to View Info or Use.";
		template.spell = spell;
		
		UIButtonMessage message = spellObject.AddComponent<UIButtonMessage>();
		message.target = gameObject;
		message.functionName = "ViewPreparedSpellOptions";
		
		ListElements.Add(spellObject);
		
		spellsPreparedSpellTemplate.SetActiveRecursively(false);
	}
	
	IEnumerator ViewPreparedSpellOptions(GameObject go)
	{
		SpellTemplate template = go.GetComponent<SpellTemplate>();
		
		List<SetterWindowDescription> optionsList = new List<SetterWindowDescription>
		{
			new SetterWindowDescription("option", "", false, new List<string>{"Use Spell", "Remove Spell", "View Info"}, false)
		};
		
		yield return StartCoroutine(HelperFunctions.SetterWindow("Do What?", optionsList));
		
		if(optionsList[0].outVariable != null)
		{
			switch(optionsList[0].outVariable)
			{
			case "Use Spell":
				UsePreparedSpell(go);
				break;
			case "Remove Spell":
				RemovePreparedSpell(go);
				break;
			case "View Info":
				ViewSpellInfo(go);
				break;
			}
		}
		
		yield break;
	}
	
	void UsePreparedSpell(GameObject go)
	{
		SpellTemplate template = go.GetComponent<SpellTemplate>();
		
		currentSelectedClass.SpellsPrepared.Remove(template.spell);
		
		int sLevel = template.spell.GetLevelFromList(currentSelectedClass.SpellList);
		
		if(sLevel > 0 && sLevel < 10)
		{	
			int currentUsedCount = int.Parse(currentSelectedClass.spellsUsed[sLevel-1]);
			currentUsedCount++;
			currentSelectedClass.spellsUsed[sLevel-1] = currentUsedCount.ToString();
		}
		
		SheetManager.SaveActiveCharacter();
		ReloadFromCurrentCharacter();
	}
	
	void RemovePreparedSpell(GameObject go)
	{
		SpellTemplate template = go.GetComponent<SpellTemplate>();
		
		currentSelectedClass.SpellsPrepared.Remove(template.spell);
		
		SheetManager.SaveActiveCharacter();
		ReloadFromCurrentCharacter();
	}
	
	void CloseAllWindows()
	{
		foreach(GameObject go in ListElements)
		{
			Destroy(go);
		}
	}
	
	IEnumerator SpellsPerDayOptions()
	{
		List<string> windowOptions = new List<string>{"Reset All Spells Used"};
		
		foreach(var spellLevel in currentSelectedClass.spellsPerDay.spellTable[currentSelectedClass.level])
		{
			if(spellLevel.Key > 0 && spellLevel.Value >= 0)
			{
				windowOptions.Add("Use Level " + spellLevel.Key + " Spell");
			}
		}
		
		List<SetterWindowDescription> options = new List<SetterWindowDescription>()
		{
			new SetterWindowDescription("","",true, windowOptions, false)
		};
		
		yield return StartCoroutine(HelperFunctions.SetterWindow("Do What?", options));
		
		if(options[0].outVariable != null)
		{
			int incrLevel = -1;
			switch(options[0].outVariable)
			{
			case "Reset All Spells Used":
				currentSelectedClass.spellsUsed = new List<string>{"0","0","0","0","0","0","0","0","0"};
				break;
			case "Use Level 1 Spell":
				incrLevel = 0;
				break;
			case "Use Level 2 Spell":
				incrLevel = 1;
				break;
			case "Use Level 3 Spell":
				incrLevel = 2;
				break;
			case "Use Level 4 Spell":
				incrLevel = 3;
				break;
			case "Use Level 5 Spell":
				incrLevel = 4;
				break;
			case "Use Level 6 Spell":
				incrLevel = 5;
				break;
			case "Use Level 7 Spell":
				incrLevel = 6;
				break;
			case "Use Level 8 Spell":
				incrLevel = 7;
				break;
			case "Use Level 9 Spell":
				incrLevel = 8;
				break;
			}
			
			if(incrLevel >= 0)
			{
				int i = int.Parse(currentSelectedClass.spellsUsed[incrLevel]);
				i++;
				currentSelectedClass.spellsUsed[incrLevel] = i.ToString();
			}
			
			SheetManager.SaveActiveCharacter();
			ReloadFromCurrentCharacter();
		}
	}
}
